## -*- mode: html; coding: utf-8; -*-
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN.
##
## CDS Invenio is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## CDS Invenio is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

<!-- WebDoc-Page-Title: Access Control Engine API -->
<!-- WebDoc-Page-Navtrail: <a class="navtrail" href="<CFG_SITE_URL>/help/hacking">Hacking CDS Invenio</a> &gt; <a class="navtrail" href="webaccess-internals">WebAccess Internals</a> -->
<!-- WebDoc-Page-Revision: $Id$ -->

<pre>
CDS Invenio Access Control Engine can be called from within your Python programs
via both a regular Python API and CLI.
In addition the you get an explanation of the program flow.

Contents:
 1. Regular API
 2. Command Line Interface
 3. Program Flow
 4. External login methods

1. Regular API

   Description:

      There is not very much information in the database at the moment.
      More can be added on demand.

      Information on these will be added when time allows it.

   Signature:

      def acc_authorize_action(req, name_action, dict={}, **arguments):
         """Check if user is allowed to perform action
         with given list of arguments.
         Return (0, message) if authentication succeeds, (error code, error message) if it fails.

         The arguments are as follows:

         req - could be either one of these three things:
               id_user of the current user
               user_info dictionary built against the user details
               req mod_python request object

 name_action - the name of the action

   arguments - dictionary with keyword=value pairs created automatically
               by python on the extra arguments. these depend on the
               given action.
         """

   Examples:

>>> # import the functions from module
>>> # change this to your local settings...
>>> from invenio.access_control_engine import *
>>> # authorize user 109 for action WebSearch_search with collection="LHC"
>>> acc_authorize_action(109, 'cfgwebsearch', collection="LHC")
      (0, "User authorized")
>>> # authorize user 109 for action WebSearch_search with collection="fail this"
>>> acc_authorize_action(109, 'cfgwebsearch', collection="fail this")
      (8, "Error (8): Incorrect keyword given for specified action.")
>>> # authorize user 109 for action BibFormat_modify with format="htmlbrief"
>>> acc_authorize_action(109, 'cfgbibformat', format="htmlbrief")
      (0, "User authorized")
>>> # authorize user foo.bar@cern.ch for action BibFormat_modify with format="htmlbrief"
>>> acc_authorize_action({'uid':109, 'email':'foo.bar@cern.ch'}, 'cfgbibformat', format="htmlbrief")
    (0, "User authorized")

2. Command Line Interface

   Description:

      The Command Line Interface uses the regular API of acc_authorize_action.

   Signature:

      authaction id_user name_action keyword1 value1 keyword2 value2 ...
          """ See description from function acc_authorize_action.
                  id_user - id of user to be authorized

	      name_action - name of the action

	         keyword1 - first keyword like in the keyword=value pairs,
                            same rules for the following ones.
			    always one word.

	           value1 - value that belongs in a pair with the corresponding keyword,
                            same rules for the following ones.
			    add quotes if it is more that one word.

              the keyword=value pairs are collected in a dictionary
          """

   Examples:

      These are the same ones as for the regular API:
      $ authaction 109 cfgwebsearch collection LHC
        0 - User authorized
      $ authaction 109 cfgwebsearch collection 'fail this'
        8 - Error (8): Incorrect keyword given for specified action.
      $ authaction 109 cfgbibformat format htmlbrief
        0 - User authorized


3. Program Flow

   this is a quick explanation of the different tasks
   performed by the authorization engine.

   I. find information for the action
     use admin API to find info.

   II. see if user is a superadmin
     query the database for connection between user and role superadmin.
     -> authorize if yes

   III. check if the user exists and find all of the users roles and create string with the ids
     query the database and build string of ids
     -> don't authorize if no roles

   IV. try to authorize without arguments
     action without arguments: query database
     -> authorize if yes
     action with optional arguments
     -> authorize if yes

   V. create list of keyword=value pairs to query the database
     run through dictionary and create string for adding to database query

   VI. find all table entries from the database
     query the database for table entries
     create list of the tuples and sort it
     -> don't authorize if no entries
     -> authorize if only 1 argument and result

   VII. combine entries and try to satisfy authorization
     dictionary with the arguments as keys, all values 0
     run throught the list created in VI
       if moving on to new authorization
         check dictionary values
         -> authorize if combination found
         reset values to 0 if not found
       set dictionary[keyword] to 1.
       (countinue loop)

   VIII. all the above failed
     -> authorization failed

4. External login methods

   If you want to call defined external loginmethods, it can be done by:

   import invenio.external_authentication
   example_method = invenio.external_authentication.example()
   example_method.auth_user("testuser", "testpassword")

   Example is here a class used as an example, which must contain the method
   auth_user.
</pre>
